# -*- encoding:utf-8 -*-
# @Time : 2025/3/12 8:58
# @Author : xunter
# @Email : 3133739348@qq.com
# @File : VerifyUtil.py
# @Software : PyCharm
import os.path
import random
import string

from PIL import Image, ImageDraw, ImageFont, ImageFilter


class ImageVerifyUtil:
    """
    生成图片验证码
    """

    def __init__(self,x=140,y=40,length=4,size=28):
        """
        :param x:图片宽
        :param y:图片高
        :param length:图片文字个数
        :param size:图片文字大小
        """
        self.x = x
        self.y = y
        self.length = length
        self.size = size

    def random_str(self):
        """
        随机生成答案
        :return:
        """
        # 文字随机生成范围  大小写 + 数字
        source = string.ascii_letters + string.digits
        # 随机挑选指定长度的文字 拼接成字符串
        return ''.join(random.sample(source, self.length))

    def random_color(self,start=0,end=255):
        """
        随机生成三原色
        需要三个随机数字的元组
        :param start:起始值
        :param end:结束值
        :return:
        """

        res = [random.randint(start, end) for i in range(3)]

        return tuple(res)


    def random_line(self,draw):
        """
        随机生成若干条干扰线
        画线需要起点和终点 线段颜色fill
        :param draw:画笔对象
        :return:
        """
        for i in range(random.randint(0,self.length)):
            lines = [(random.randint(0,self.x),random.randint(0,self.y)) for i in range(2)]
            draw.line(lines, fill=self.random_color(22,222))


    def random_point(self,draw,rate):
        """
        随机生成干扰点
        画点需要(x,y)坐标 点的颜色
        :param draw:画笔对象
        :param rate:干扰点频率 (1,100)随机数 大于rate就点
        :return:
        """
        for i in range(self.x):
            for j in range(self.y):
                if random.randint(1,100) <= rate:
                    draw.point((i,j), fill=self.random_color(11,111))

    def verify_code(self):
        """
        组装验证码
        生成画布 Image.new('RGB',(宽高),(画布背景颜色))
        获取字体对象 找到字体文件文件夹
        在画布上创建画笔对象
        绘制干扰线和干扰点
        绘制文字答案  先得到随机的文字答案  依次将答案画到画板上 ((文字坐标轴),文字,font=字体,字体颜色(三,原,色))
        增加高斯模糊滤镜
        :return:
        """
        image = Image.new('RGB',(self.x,self.y),(255,255,255))
        draw = ImageDraw.Draw(image)
        file = os.path.dirname(os.path.abspath(__file__))
        font = ImageFont.truetype(f'{file}/HYYakuHei-85W.ttf',self.size)
        self.random_line(draw)
        self.random_point(draw,20)
        code = self.random_str()
        for i in range(self.length):
            draw.text((i*35,random.randint(3,6)),code[i],font=font, fill=self.random_color(22,222))

        # image = image.filter(ImageFilter.BLUR)
        return image,code


if __name__ == '__main__':
    verify = ImageVerifyUtil()
    image,code = verify.verify_code()
    with open('code.png','wb') as f:
        image.save(f)
    print(code)